<?php
/*
/**
* CHRONOFORMS version 3.0 
* Copyright (c) 2008 Chrono_Man, ChronoEngine.com. All rights reserved.
* Author: Chrono_Man (ChronoEngine.com)
* @license		GNU/GPL
* See readme.html.
* Visit http://www.ChronoEngine.com for regular update and information.
**/
defined('_JEXEC') or die('Restricted access'); 

class CFChronoForm extends JObject{
	var $formrow = NULL;
	var $formparams = NULL;
	var $formerrors = '';
	var $formdebug = '';
	var $error_found = false;
	var $stoprunning = false;
	var $haltFunction = array('emails' => false, 'uploads' => false, 'plugins_before_email' => false, 'plugins_after_email' => false, 'autogenerated_before_email' => false, 'autogenerated_after_email' => false, 'onsubmitcode' => false, 'onsubmitcodeb4' => false);
	var $tablerow = array();
	var $posted = array();
	var $pagetype = 'chronocontact';
	var $formname = '';
	var $stoploading = false;
	var $submission_complete = false;
	function __construct($formname = ''){
		if (!empty($formname)) {
			$this->getForm(trim($formname));
		}
		else
		{
			//todo: need to load default table properties
			//initialise			
			$this->getForm(trim($formname));
		}
	}
	function &getInstance($formname = ''){
		static $instances;
		global $mainframe;
		if (!isset ($instances)) {
			$instances = array ();
		}
		if (empty($formname)) {
			if(JRequest::getVar('chronoformname')){
				JRequest::setVar('chronoformname', preg_replace('/[^A-Za-z0-9_]/', '', JRequest::getVar('chronoformname')));
			}
			$formname = JRequest::getVar('chronoformname');
			if ( !$formname ) {
				$params =& $mainframe->getPageParameters('com_chronocontact');
				$formname = preg_replace('/[^A-Za-z0-9_]/', '', $params->get('formname'));
			}
		}
		if(empty($instances[trim($formname)])){
			$instances[trim($formname)] = new CFChronoForm($formname);
			return $instances[trim($formname)];
		}else{
			//$instances = array (new CFChronoForm($formname));
			return $instances[trim($formname)];
		}
	}
	function getForm( $formname )
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		if(!trim($formname)){
			if(JRequest::getVar('chronoformname')){
				JRequest::setVar('chronoformname', preg_replace('/[^A-Za-z0-9_]/', '', JRequest::getVar('chronoformname')));
			}
			$formname = JRequest::getVar('chronoformname');
			if ( !$formname ) {
				$params =& $mainframe->getPageParameters('com_chronocontact');
				$formname = preg_replace('/[^A-Za-z0-9_]/', '', $params->get('formname'));
			}
		}
		$query     = "SELECT * FROM `#__chrono_contact` WHERE `name` = '".$formname."'";
		$database->setQuery( $query );
		$cf_rows = $database->loadObjectList();
		
		if(count($cf_rows)){
			$this->formrow = $cf_rows[0];
			$this->formname = "ChronoContact_".$this->formrow->name;
			//load titles
			$registry = new JRegistry();
			$registry->loadINI( $cf_rows[0]->titlesall );
			$titlesvalues = $registry->toObject( );
			//load params
			$paramsvalues = new JParameter($this->formrow->paramsall);
			$this->formparams = $paramsvalues;		
			return true;
		}else{
			$emptyForm = new StdClass();
			$emptyForm->id = 0;
			$emptyForm->name = '';
			$this->formrow = $emptyForm;
			$paramsvalues = new JParameter('');
			$this->formparams = $paramsvalues;
			return false;
		}
	}
	
	function formparams($key, $default = '')
	{
		//$paramsvalues = new JParameter($this->formrow->paramsall);
		return $this->formparams->get($key, $default);
	}	
	
	function setFormParam( $param, $value )
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		$this->formparams->set($param, $value);
	}
	function setFormData( $key, $value )
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		$this->formrow->$key = $value;
	}
	
	function getFormName( $formid )
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		$query     = "SELECT * FROM `#__chrono_contact` WHERE `id` = '".$formid."'";
		$database->setQuery( $query );
		$cf_rows = $database->loadObjectList();
		
		if(count($cf_rows)){
			return $cf_rows[0]->name;
		}else{
			return false;
		}
	}
	
	function setFormName( $newformname )
	{
		$this->formname = $newformname;
	}
	
	function addErrorMsg( $text )
	{
		$this->formerrors = $this->formerrors.'<li>'.$text.'</li>';
	}
	function addDebugMsg( $text )
	{
		$this->formdebug = $this->formdebug.'<li>'.$text.'</li>';
	}	
	
	function showForm($formname, $posted = array(), $runplugins = true)
	{		
		$MyForm =& CFChronoForm::getInstance($formname);
		if(!$MyForm->formrow->id){
			echo "There is no form with this name";
			return;
		}
		$session =& JFactory::getSession();
		//if(!trim($session->get('cfreturnurl_'.$formname, '', md5('chrono')))){
			$session->clear('chrono_form_errors_'.$formname, md5('chrono'));
			$session->clear('chrono_form_data_'.$formname, md5('chrono'));
			$session->clear('cfreturnurl_'.$formname, md5('chrono'));
		//}
		if( trim($MyForm->formparams('enmambots')) == 'Yes'){
			$MyForm->runMambots($MyForm->formrow->name);
		}
		if($runplugins){
			$MyPlugins =& CFPlugins::getInstance($MyForm->formrow->id);
			$MyPlugins->runPlugin('', array('ONLOAD', 'ONLOADONSUBMIT'));
		}
		if(!$MyForm->stoploading){	
			HTML_ChronoContact::showform( $MyForm->formrow, $posted);
		}
	}
	
	function runMambots($formname){
		global $mainframe;
		$MyForm =& CFChronoForm::getInstance($formname);
		$params        =& $mainframe->getParams('com_content');
		$dispatcher       =& JDispatcher::getInstance();
		$type = 'content';
		JPluginHelper::importPlugin($type);
		$rowmam->text = $MyForm->formrow->html;
		$results_mambots = $mainframe->triggerEvent( 'onPrepareContent', array (&$rowmam, & $params, 0 ));
		$MyForm->formrow->html = $rowmam->text;	
	}
	
	function getAction($formname){
		global $mainframe;
		$CF_PATH = ($mainframe->isSite()) ? JURI::Base() : $mainframe->getSiteURL();
		$MyForm =& CFChronoForm::getInstance($formname);
		if(!empty($MyForm->formrow->submiturl)){ 
			$actionurl = $MyForm->formrow->submiturl;			
		} else {
			$actionurl = $CF_PATH.'index.php?option=com_chronocontact&amp;task=send&amp;chronoformname='.$MyForm->formrow->name;
			if((int)JRequest::getVar('Itemid')){
				$actionurl = $actionurl.'&amp;Itemid='.JRequest::getVar('Itemid');
			}
		}
		return $actionurl;
	}
	
	function selfURL() {
		$uri =& JURI::getInstance();
		$inbetween = '';
		if($uri->getQuery())$inbetween = '?';
		return $uri->current().$inbetween.$uri->getQuery();
	}
	
	function checkSubmissionsLimit($formname)
	{		
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);		
		if(trim($MyForm->formparams('submissions_limit'))){
			if(!$session->get('chrono_submissions_limit_'.$formname, '', md5('chrono'))){
				$session->set("chrono_submissions_limit_".$formname, mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+1, date("Y")), md5('chrono'));
			}else{
				if(($session->get('chrono_submissions_limit_'.$formname, '', md5('chrono')) + ((int)trim($MyForm->formparams('submissions_limit')))) > mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+1, date("Y"))){
					$MyForm->addErrorMsg($MyForm->formparams('submissions_limit_error', 'Sorry but you can not submit the form again very soon like this!'));
				}else{
					$session->set("chrono_submissions_limit_".$formname, mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+1, date("Y")), md5('chrono'));
				}
			}
		}
	}
	
	function resetSubmissionsLimit($formname)
	{
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);
		$session->set("chrono_submissions_limit_".$formname, '', md5('chrono'));
	}
	
	function checkImageVerification($formname)
	{
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);
		if ( trim($MyForm->formparams('imagever')) == 'Yes' ) {
			$sessionvar = $session->get('chrono_verification', '', md5('chrono'));
			$chrono_verification = strtolower(JRequest::getVar('chrono_verification'));
			if ( md5($chrono_verification ) != $sessionvar ) {
				$MyForm->addErrorMsg($MyForm->formparams('imgver_error_msg', 'You have entered an incorrect verification code at the bottom of the form.'));
			}else{
				$session->clear('chrono_verification', md5('chrono'));
				//$session->clear('chrono_verification_msg');
			}
		}
	}
	
	function checkServerValidation($formname)
	{
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);
		if ( trim($MyForm->formparams('servervalidate')) == 'Yes' ) {
			if ($returnval = eval( "?>".$MyForm->formrow->server_validation )){
				$MyForm->resetSubmissionsLimit($formname);
				$MyForm->addErrorMsg($returnval);
			}
		}
	}
	
	function showFormErrors($formname)
	{
		global $mainframe;
		$session =& JFactory::getSession();
		$posted = JRequest::get( 'post' , JREQUEST_ALLOWRAW );
		$MyForm =& CFChronoForm::getInstance($formname);
		if($MyForm->formerrors){
			if($session->get('cfreturnurl_'.$formname, '', md5('chrono'))){				
				$session->set("chrono_form_errors_".$formname, $MyForm->formerrors, md5('chrono'));
				$session->set("chrono_form_data_".$formname, $MyForm->posted, md5('chrono'));				
				//$mainframe->redirect(str_replace('&cfshowerrors=1', '', JRequest::getVar('cfreturnurl')).'&cfshowerrors=1');
				
				$mainframe->redirect($session->get('cfreturnurl_'.$formname, '', md5('chrono')));
			}
			//$MyForm->showForm($MyForm->formrow->name, $posted);
			return true;
		}else{
			//$session->clear('chrono_form_errors_'.$formname, md5('chrono'));
			//$session->clear('chrono_form_data_'.$formname, md5('chrono'));
		}
		return false;
	}
	
	function generateCFToken($formname)
	{	
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);
		$secret = $MyForm->formparams('secret', 'ILIKECHRONOFORMS');
		/*if($session->get('chrono_secret_check_'.$formname, '', md5('chrono'))){
			return md5(trim($secret).$session->get('chrono_secret_check_'.$formname, '', md5('chrono'));
		}else{
			//srand((double)microtime()*10000);
			//$inum	=	substr(base64_encode(md5(rand())), 0, 16);
			//$session->set('chrono_secret_check_'.$formname, $inum, md5('chrono'));
			return md5(trim($secret).$session->getId());
		}*/
		return md5(trim($secret).$session->getId());
	}
	
	function checkCFToken($formname)
	{	
		global $mainframe;
		$session =& JFactory::getSession();
		$MyForm =& CFChronoForm::getInstance($formname);
		$secret = $MyForm->formparams('secret', 'ILIKECHRONOFORMS');
		/*if($session->get('chrono_secret_check_'.$formname, '', md5('chrono'))){
			if(md5(trim($secret).$session->getId() == JRequest::getVar('1cf1'))){
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}*/
		if(md5(trim($secret).$session->getId() == JRequest::getVar('1cf1'))){
			return true;
		}else{
			return false;
		}
	}
	
	function handleArrays($formname){
		global $mainframe;
		$posted = JRequest::get( 'post' , JREQUEST_ALLOWRAW );
		$MyForm =& CFChronoForm::getInstance($formname);
		/**
		 * Associate field values with names and implode arrays
		 */
		$fields = array();
		$names = explode(",", str_replace("[]", "" , $MyForm->formrow->fieldsnames));
		foreach($names as $name){
			$fields[$name] = '';
		}
		foreach ( $posted as $name => $post ) {
			if($MyForm->formparams('handlepostedarrays', 'Yes') == 'Yes'){
				if(isset($post)){
					if ( is_array($post)) {
						$fields[$name] = implode(", ", $post);
						JRequest::setVar($name, implode(", ", $post));
					} else {
						$fields[$name] = $post;
					}
				}else{
					$fields[$name] = '';
				}
			}else{
				$fields[$name] = $post;
			}
		}
		return $fields;
	}
	
	function submitForm($formname, $posted = array(), $useCurrent = false)
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		if(empty($posted)){
			$posted = JRequest::get( 'post' , JREQUEST_ALLOWRAW );
		}
		if($useCurrent){
			$MyForm = $this->getInstance($formname);
		}else{
			$MyForm =& CFChronoForm::getInstance($formname);
		}
		$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
		$MyCustomCode =& CFCustomCode::getInstance($MyForm->formrow->id);
		$MyPlugins =& CFPlugins::getInstance($MyForm->formrow->id);
		
		$MyForm->posted = $posted;
		$debug = $MyForm->formparams('debug');		
		$MyForm->addDebugMsg('Form passed first SPAM check OK');		
		$session =& JFactory::getSession();	
		// Check how soon was the last submission
		$MyForm->checkSubmissionsLimit($MyForm->formrow->name);	
		$MyForm->addDebugMsg('Form passed the submissions limit (if enabled) OK');		
		/**
		 * If imageversification is on check the code
		 */
		$MyForm->checkImageVerification($MyForm->formrow->name);
		$MyForm->addDebugMsg('Form passed the Image verification (if enabled) OK');		
		//Server side validation	
		$MyForm->checkServerValidation($MyForm->formrow->name);
		$MyForm->addDebugMsg('Form passed the server side validation (if enabled) OK');		
		//if any check steps failed, quit and reshow the form
		if($MyForm->showFormErrors($MyForm->formrow->name)){
			$MyForm->showForm($MyForm->formrow->name, $posted);
			return;
		}
		/**
		 * if $debug is true then ChronoForms will show diagnostic output
		 */   
		$MyForm->addDebugMsg("\$_POST Array: ".print_r($posted, true));
		$MyForm->addDebugMsg("\$_FILES Array: ".print_r($_FILES, true));
		/**
		 * Upload attachments
		 */
		if(!$MyForm->haltFunction["uploads"]){
			$MyUploads =& CFUploads::getInstance($MyForm->formrow->id);
			$MyUploads->handleUploads();
			//show errors if any
			if($MyForm->showFormErrors($MyForm->formrow->name)){
				$MyForm->showForm($MyForm->formrow->name, $posted);
				return;
			}
		}
		/* Do Onsubmit before_email plugins*/
		if(!$MyForm->haltFunction["plugins_before_email"]){			
			$MyPlugins->runPlugin('before_email');		
			$MyForm->addDebugMsg('Form passed the plugins step (if enabled) OK');
			//show errors if any
			if($MyForm->showFormErrors($MyForm->formrow->name)){
				$MyForm->showForm($MyForm->formrow->name, $posted);
				return;
			}	
		}
		//handle arrays
		$MyForm->handleArrays($MyForm->formrow->name);	
		/**
		 * If there are no errors and e-mail is required then build and send it.
		 */
		if ( ($MyForm->formrow->emailresults) && !$MyForm->error_found && !$MyForm->stoprunning ) {		
			//run before submit code
			if(!$MyForm->haltFunction["onsubmitcodeb4"]){
				$MyCustomCode->runCode( 'onsubmitcodeb4' );
				if($MyForm->showFormErrors($MyForm->formrow->name)){
					$MyForm->showForm($MyForm->formrow->name, $posted);
					return;
				}
			}
			if(!$MyForm->haltFunction["autogenerated_before_email"]){
				$MyCustomCode->runCode( 'autogenerated', 'before_email' );
			}		
			//send emails
			if(!$MyForm->haltFunction["emails"]){
				$emails_result = $MyFormEmails->sendEmails($MyForm, $MyFormEmails->emails);		
			}	
		}	
	
		if ( !$MyForm->error_found && !$MyForm->stoprunning ) {
		/*************** check to see if order was specified, if not then use the default old one ************************/
			if((!$MyForm->formparams('plugins_order'))&&(!$MyForm->formparams('onsubmitcode_order'))&&(!$MyForm->formparams('autogenerated_order'))){
				$MyForm->setFormParam('autogenerated_order', 3);
				$MyForm->setFormParam('onsubmitcode_order', 2);
				$MyForm->setFormParam('plugins_order', 1);
			}
	
			for($ixx = 1 ; $ixx <= 3; $ixx++){
				if($MyForm->formparams('plugins_order') == $ixx){
					if(!$MyForm->haltFunction["plugins_after_email"]){
						$MyPlugins->runPlugin('after_email');
						//show errors if any
						if($MyForm->showFormErrors($MyForm->formrow->name)){
							$MyForm->showForm($MyForm->formrow->name, $posted);
							return;
						}
					}
				}
				/**
				 * Run the On-submit 'post e-mail' code if there is any
				 */
				if($MyForm->formparams('onsubmitcode_order') == $ixx){
					if(!$MyForm->haltFunction["onsubmitcode"]){
						$MyCustomCode->runCode( 'onsubmitcode' );
						if($MyForm->showFormErrors($MyForm->formrow->name)){
							$MyForm->showForm($MyForm->formrow->name, $posted);
							return;
						}
					}
				}
	
				/**
				 * Run the SQL query if there is one
				 */
				if($MyForm->formparams('autogenerated_order') == $ixx){
					if(!$MyForm->haltFunction["autogenerated_after_email"]){
						$MyCustomCode->runCode( 'autogenerated', 'after_email' );
					}
				}
			}	
			//Mark submission as complete!
			$MyForm->submission_complete = true;		
			$MyForm->addDebugMsg('Debug End');			
			/**
			 * Redirect the page if requested
			 */
			if ( !empty($MyForm->formrow->redirecturl) ) {
				if ( !$debug ) {
					$mainframe->redirect($MyForm->formrow->redirecturl);
				} else {
					$MyForm->addDebugMsg("<div class='debug' >Redirect link set, click to test:<br /><a href='".$MyForm->formrow->redirecturl."'>".$MyForm->formrow->redirecturl."</a></div>");
				}
			}
		}
		if((!empty($MyForm->formdebug))&&($MyForm->formparams('debug') == '1')){
			include_once(JPATH_COMPONENT.DS.'libraries'.DS.'includes'.DS.'Debug.php');
		}
	}
	
	function doExtra($formname, $extraid = 1, $posted = array())
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		if(empty($posted)){
			$posted = JRequest::get( 'post' , JREQUEST_ALLOWRAW );
		}
		if(empty($extraid)){
			$extraid = 1;
		}
		if(((int)$extraid == 0)||($extraid > 5)){
			return false;
		}
		$MyForm =& CFChronoForm::getInstance($formname);
		if ( !empty($MyForm->formrow->{"extra".$extraid}) ){
			eval( "?>".$MyForm->formrow->{"extra".$extraid} );
		}else{
			return false;
		}		
	}
	
	function addhash()
	{
		global $mainframe;
		$database =& JFactory::getDBO();
		$query     = "SELECT * FROM `#__components` WHERE `option` = 'com_chronocontact' AND parent='0' AND admin_menu_link='option=com_chronocontact'";
		$database->setQuery( $query );
		$result = $database->loadObject();
		//$configs = JComponentHelper::getParams('com_chronocontact');
		$configs = new JParameter($result->params);
		if($configs->get('licensevalid', 0)){
			return '';
		}else{
			return base64_decode('PCEtLSBkb24ndCByZW1vdmUgdGhlIGZvbGxvd2luZyAzIGxpbmVzIGlmIHlvdSBkaWRuJ3QgYnV5IGEgc3Vic2NyaXB0aW9uIC0tPiANCjxkaXYgY2xhc3M9ImNocm9ub2Zvcm0iPg0KPGEgaHJlZj0iaHR0cDovL3d3dy5jaHJvbm9lbmdpbmUuY29tIj5Qb3dlcmVkIEJ5IENocm9ub0Zvcm1zIC0gQ2hyb25vRW5naW5lLmNvbTwvYT4NCg0KPC9kaXY+DQo8IS0tIGRvbid0IHJlbW92ZSB0aGUgMyBsaW5lcyBhYm92ZSBpZiB5b3UgZGlkbid0IGJ1eSBhIHN1YnNjcmlwdGlvbiAtLT4=');
		}
	}
	
	function cfskipregex($regex){
		$reserved = array('[', ']');
		$replace = array('\[', '\]');
		return str_replace($reserved, $replace, $regex);
	}
	
}